// 17_rayon.rs
// Rust Rayon 并行计算库教程

use rayon::prelude::*;
use std::time::Instant;
// 移除了 chrono 依赖，使用标准库的时间功能
// 移除了未使用的 std::sync::Arc 导入

// 格式化当前时间的函数，使用标准库替代 chrono
fn format_current_time() -> String {
    // 使用系统时间戳作为简单的时间表示
    use std::time::{SystemTime, UNIX_EPOCH};
    if let Ok(duration) = SystemTime::now().duration_since(UNIX_EPOCH) {
        format!("{:.3}", duration.as_secs_f64())
    } else {
        "0.000".to_string()
    }
}

fn main() {
    println!("=== Rayon 并行计算库教程 ===");
    
    // 1. 基本并行迭代
    println!("\n1. 基本并行迭代");
    
    let data: Vec<i32> = (1..=1000000).collect(); // 减少数据量以避免溢出
    
    // 串行处理
    let start = Instant::now();
    let serial_result: Vec<i32> = data.iter()
        .map(|x| x * 3)
        .collect();
    let serial_duration = start.elapsed();
    
    // 并行处理
    let start = Instant::now();
    let parallel_result: Vec<i32> = data.par_iter()
        .map(|x| x * 3)
        .collect();
    let parallel_duration = start.elapsed();
    
    println!("串行处理时间: {:?}", serial_duration);
    println!("并行处理时间: {:?}", parallel_duration);
    println!("结果一致性检查: {}", serial_result == parallel_result);
    
    // 2. 并行迭代器操作
    println!("\n2. 并行迭代器操作");
    
    // 并行过滤和映射
    let filtered: Vec<i32> = data.par_iter()
        .filter(|&x| x % 2 == 0)
        .map(|x| x * 2)
        .collect();
    
    println!("偶数乘以2的结果前10个: {:?}", &filtered[..10.min(filtered.len())]);
    
    // 并行归约操作 (使用较小的数据避免溢出)
    let small_data: Vec<i32> = (1..=10).collect();
    let sum: i32 = small_data.par_iter().sum();
    let product: i64 = small_data.par_iter().map(|&x| x as i64).product(); // 转换为 i64 避免溢出
    let max_value = small_data.par_iter().max();
    let min_value = small_data.par_iter().min();
    
    println!("并行求和: {}", sum);
    println!("并行求积: {}", product);
    println!("最大值: {:?}", max_value);
    println!("最小值: {:?}", min_value);
    
    // 3. 并行排序
    println!("\n3. 并行排序");
    
    let mut unsorted_data: Vec<i32> = vec![64, 34, 25, 12, 22, 11, 90, 5];
    println!("排序前: {:?}", unsorted_data);
    
    unsorted_data.par_sort();
    println!("并行排序后: {:?}", unsorted_data);
    
    // 4. 并行数组操作
    println!("\n4. 并行数组操作");
    
    let mut arr = [4, 2, 6, 1, 9, 3, 8, 5, 7, 0];
    println!("数组操作前: {:?}", arr);
    
    // 并行排序
    arr.par_sort();
    arr.reverse();
    println!("并行排序后: {:?}", arr);
    
    // 并行修改数组元素
    arr.par_iter_mut().for_each(|x| *x *= 2);
    println!("每个元素乘以2后: {:?}", arr);
    
    // 5. 自定义线程池配置
    println!("\n5. 自定义线程池配置");
    
    // 创建自定义线程池
    let pool = rayon::ThreadPoolBuilder::new()
        .num_threads(4)
        .thread_name(|index| format!("自定义线程-{}", index))
        .build()
        .unwrap();
    
    // 在自定义线程池中执行任务
    pool.install(|| {
        let data: Vec<i32> = (1..=10).collect();
        let result: Vec<i32> = data.par_iter()
            .map(|x| {
                println!("{} 线程 {:?} 处理 {}", format_current_time(), std::thread::current().name(), x);
                x * x
            })
            .collect();
        println!("自定义线程池结果: {:?}", result);
    });
    
    // 指定线程程执行任务
    let results: Vec<i64> = (1..=10).into_par_iter().map(|i| {
        pool.install(move || {
            let rs = (i as i64) * (i as i64); // 使用 i64 防止溢出
            println!("{} 第{}个任务 线程 {:?} 处理结果 {}", format_current_time(), i, std::thread::current().name(), rs);
            rs
        })
    }).collect();
    
    // 打印所有结果
    for (i, rs) in results.iter().enumerate() {
        println!("第{}个任务结果: {}", i + 1, rs);
    }
    // 指定线程程执行任务
    (1..=10).into_par_iter().for_each(|i| {
        pool.install(move || {
            let rs = (i as i64) * (i as i64); // 使用 i64 防止溢出
            println!("{} 第{}个任务 线程 {:?} 处理结果 {}", format_current_time(), i, std::thread::current().name(), rs);
            println!("第{}个任务结果: {}", i, rs);
        });
    });
    

    // 6. 并行搜索和查找
    println!("\n6. 并行搜索和查找");
    
    let large_data: Vec<i64> = (1..=1000000).collect(); // 使用 i64 避免潜在的溢出
    
    // 并行查找
    let found = large_data.par_iter().find_any(|&&x| x == 500000);
    println!("并行查找 500000: {:?}", found);
    
    // 并行任意匹配
    let any_even = large_data.par_iter().any(|&x| x % 2 == 0);
    let all_positive = large_data.par_iter().all(|&x| x > 0);
    println!("是否存在偶数: {}", any_even);
    println!("是否所有数都为正: {}", all_positive);
    
    // 7. 并行折叠操作
    println!("\n7. 并行折叠操作");
    
    let folded_result: i64 = data.par_iter().map(|&x| x as i64).fold_with(
        0i64,  // 初始值
        |acc, x| acc + x * 2  // 每个线程内的折叠操作
    ).sum();  // 将所有线程的结果求和
    
    println!("并行折叠结果: {}", folded_result);
    
    // 8. 错误处理
    println!("\n8. 错误处理");
    
    let results: Result<Vec<i32>, &'static str> = data[..10.min(data.len())].par_iter() // 只处理前10个元素避免除零
        .map(|&x| {
            if x == 0 {
                Err("遇到零值")
            } else {
                Ok(100 / x)
            }
        })
        .collect();
    
    match results {
        Ok(values) => println!("所有计算成功，结果数量: {}", values.len()),
        Err(e) => println!("计算出错: {}", e),
    }
    
    // 9. 并行处理复杂数据结构
    println!("\n9. 并行处理复杂数据结构");
    
    #[derive(Debug, Clone)]
    struct Person {
        #[allow(dead_code)]
        name: String,
        age: u32,
        salary: f64,
    }
    
    let people = vec![
        Person { name: "Alice".to_string(), age: 30, salary: 50000.0 },
        Person { name: "Bob".to_string(), age: 25, salary: 45000.0 },
        Person { name: "Charlie".to_string(), age: 35, salary: 60000.0 },
        Person { name: "Diana".to_string(), age: 28, salary: 55000.0 },
    ];
    
    // 并行计算平均年龄
    let total_age: u32 = people.par_iter().map(|p| p.age).sum();
    let average_age = total_age as f64 / people.len() as f64;
    println!("平均年龄: {:.2}", average_age);
    
    // 并行查找高薪人员
    let high_earners: Vec<&Person> = people.par_iter()
        .filter(|p| p.salary > 50000.0)
        .collect();
    println!("高薪人员数量: {}", high_earners.len());
    
    // 10. 并行处理大数据集
    println!("\n10. 并行处理大数据集");
    
    let large_dataset: Vec<f64> = (1..=100000).map(|x| x as f64 * 0.1).collect();
    
    // 并行计算统计数据
    let sum: f64 = large_dataset.par_iter().sum();
    let count = large_dataset.len();
    let average = sum / count as f64;
    
    // 查找最大值和最小值
    let max_value = large_dataset.par_iter().cloned().reduce(
        || f64::NEG_INFINITY,
        |a, b| a.max(b)
    );
    
    let min_value = large_dataset.par_iter().cloned().reduce(
        || f64::INFINITY,
        |a, b| a.min(b)
    );
    
    println!("大数据集统计:");
    println!("  元素数量: {}", count);
    println!("  总和: {:.2}", sum);
    println!("  平均值: {:.2}", average);
    println!("  最大值: {:.2}", max_value);
    println!("  最小值: {:.2}", min_value);
    
    println!("\nRayon 并行计算库教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_format_current_time() {
        let time_str = format_current_time();
        // 验证返回的是一个非空字符串
        assert!(!time_str.is_empty());
    }
    
    #[test]
    fn test_basic_parallel_operations() {
        let data: Vec<i32> = (1..=100).collect();
        
        // 测试并行映射
        let result: Vec<i32> = data.par_iter().map(|x| x * 2).collect();
        assert_eq!(result.len(), 100);
        assert_eq!(result[0], 2);
        assert_eq!(result[99], 200);
        
        // 测试并行过滤
        let filtered: Vec<&i32> = data.par_iter().filter(|&x| x % 2 == 0).collect();
        assert_eq!(filtered.len(), 50);
        
        // 测试并行求和
        let sum: i32 = data.par_iter().sum();
        assert_eq!(sum, 5050);
    }
    
    #[test]
    fn test_parallel_sorting() {
        let mut data: Vec<i32> = vec![5, 2, 8, 1, 9, 3];
        data.par_sort();
        assert_eq!(data, vec![1, 2, 3, 5, 8, 9]);
    }
    
    #[test]
    fn test_custom_thread_pool() {
        let pool = rayon::ThreadPoolBuilder::new()
            .num_threads(2)
            .build()
            .unwrap();
            
        let result = pool.install(|| {
            (1..=10).into_par_iter().map(|x| x * x).sum::<i32>()
        });
        
        assert_eq!(result, 385); // 1^2 + 2^2 + ... + 10^2 = 385
    }
}